/**************************************************************************
 * @doc CPACSRC
 * @module CPACCLRK.C |  
 * Source code for handling the custom clerk operations
 * Product         :   SoftPay 2000 (Global Payment Methodology).
 * <nl>Developer   :   Kelvin_F2
 * <nl>Notes       :
 * @head3 Custom Functions |
 * @index | Print
 * @end
 *
 * Copyright (c) 1996-2000 by VeriFone Inc. All rights reserved.
 * 
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form 
 * or by any means whether electronic, mechanical, magnetic, optical, 
 * or otherwise, without the express prior written permission of VeriFone, Inc.
 *
 * Revision History
 * ------------------------------------------------------------------------
 $Log: /SoftPay/SPK2SIM/Source/cpacsrc/cpacclrk.c $
 * 
 * ------------------------------------------------------------------------
 ********************************************************************************/
#include <project.h>
#ifdef CLERK_DEFINED

// #define CPACCLRK_C

#include <aclconio.h>
#include <txoinc.h>
#include <ascii.h>
#include <errno.h>
#include <applidl.h>
#include <printer.h>
#include <formater.h>
#include <message.h>
#include <acldev.h>
#include <actutil.h>

/** /#define DEBUG_VSPRINT*/
#ifdef DEBUG_VSPRINT
#define DEBUG_95
#endif

#include <define.h>
#include <transact.h>
#include <print.h>
#include <gds.h>
#include <lct.h>
#include <tct.h>
#include <hdt.h>
#include <mht.h>
#include <pct.h>
#include <ui.h>
#include <msg.h>
#include <msgfuncs.h>
#include <form.h>
#include <stats.h>
#include <paramrpt.h>
#include <logo.h>
#include <tran.h>
#include <table.h>
#include <stdlib.h>
#include <aclstr.h>
#include <string.h>
//#include <beetle.h>

#include <spdebug.h>
#include <init.h>
#include <util.h>
#include <confio.h>
#include <oper.h>
#include <entry.h>
#include <file.h>
#include <card.h>
#include <cardmsg.h>
#include <funcids.h>
#include <accum.h>
#include <spamsg.h>
#include <multilng.h>
#include <format.h>
#include <date.h>
#include <ui.h>
#include <isoload.h>
#include <pbatch.h>
#include <cdt.h>
#include <settlbat.h>
#include <stats.h>
#include <menus.h>
//#include <report.h>
#include <udt.h>
#include <msgclrk.h>
#include <clerk.h>

#include "cpacclrk.h"
#include "cpacoper.h"
#include "cpacmsg.h"
#include "cpacsize.h"
#include "sqautils.h"
#include "cpac.h"
#include "cpacbat.h"
#include "custoper.h"
#include "cpacextn.h"
#include "cpacids.h"
#include "batmsg.h"


#ifndef lnSelectAppTypePrompt
#define lnSelectAppTypePrompt(lnMsgId1, lnMsgId2) (inGetApplicationType() == RETAIL ? lnMsgId1 : lnMsgId2)
#endif


//Kelvin_f2 --- start: clerk logon/logoff
/********************************************************************************************* 
* @func int | inCPACGetClerkID |
*    
*  Validate the Clerk id entered by the user.
   and verify user is defined in UDT.
* 
* @rdesc return values.
* @flag int    |  VS_ESCAPE, VS_SUCCESS
* @end
**********************************************************************************************/

int inCPACGetClerkID(TRANSACTION_OBJECT* pobTran) {
    char szClerkID[CLERK_ID_SIZE + 1];
    int inResult = VS_SUCCESS;
    VS_BOOL fScrollDisplay = !(obDisp.blNoScrollEntries);

    pdebug(("--inGetClerkId--"));

    int2str(szClerkID, 0);
    strlcpy(pobTran->srBKey.szClerkId, szClerkID, CLERK_ID_SIZE);
    if (inGetClerkMode() == CLERK_PROMPT) {
        if ((inResult = inEnterWithMessage(lnSelectAppTypePrompt(CLERK_ID_MSG, SERVER_ID_MSG), fScrollDisplay, szClerkID, INPUT_ALNUMS, CLERK_ID_SIZE, inValidateClerk)) >= 0) {
            strlcpy(pobTran->srBKey.szClerkId, szClerkID, CLERK_ID_SIZE);
            return(VS_SUCCESS);
        }
    }

    /* Checks if clerk is logged on             */
    if (inGetClerkMode() == CLERK_LGN) {
        if ((inResult = inCPACGetUDTAnyoneLogedIn(pobTran)) != VS_SUCCESS)
            while ((inResult = inCheckLogOn(pobTran)) != VS_SUCCESS) {
                vdClearStatusMessage();

                if (inResult == VS_ESCAPE)
                    return(inResult);  /* fix for invalid password bug */

                else if (act_kbd_pending_test(KEY_CANCEL) == 1)
                    return(VS_ESCAPE);
            }
    }

    return(inResult);
}

/********************************************************************************************* 
* @func int | inCPACGetUDTAnyoneLogedIn |
*  
*  Check if there any clerk logged in, return VS_SUCCESS if someone loged in
*                                      return VS_FAILURE if no one loged in
*                                      return VS_ESCAPE if CANCEL press
*                                      return VS_ERR if Error occur
*    
* @rdesc return values.
* @flag int    |  VS_SUCCESS, VS_ESCAPE if cancelled, VS_ERR if match not found,
*                  VS_FAILURE if file errors
*                 
* @end
**********************************************************************************************/

int inCPACGetUDTAnyoneLogedIn(TRANSACTION_OBJECT* pobTran) {
    int inResult = VS_FAILURE;
    int inRecordSize;
    UDT_REC srUDTRec;
    FHANDLE hUDTFHandle;
    //char chPassword[PASSWORD_SIZE+1];
    int inOperationCode;  /* pj1 */
    char* chNull = 0;

    inOperationCode = inGGOpCode(); /* pj1 */

    inRecordSize = 0;

    if ((hUDTFHandle = open(UDT_FILENAME, O_RDWR)) >= 0) {
        if (lseek(hUDTFHandle, (long) GEN_VER_SIZE, SEEK_SET) == (long) GEN_VER_SIZE)
            do {
                if ((inRecordSize = read(hUDTFHandle, (char *) &srUDTRec, SIZE_UDT_REC)) == SIZE_UDT_REC) {
                    if (srUDTRec.inLogedIn == VS_TRUE) {
                        inResult = VS_SUCCESS;
                        strlcpy(pobTran->srBKey.szClerkId, srUDTRec.szClerkId, CLERK_ID_SIZE);
                        close(hUDTFHandle);
                        return (inResult);
                    }
                }
            } while (inRecordSize == SIZE_UDT_REC);
        close(hUDTFHandle);
    }
    /* Get out in Clear key press */
    if (act_kbd_pending_test(KEY_CANCEL))
        return (VS_ESCAPE);
    if (inRecordSize <= 0)
        return(VS_ERR);

    return(inResult);
}
/********************************************************************************************* 
* @func int | inCPACInitLogInOperation |
* This is Init LogIn Operation called in boot up sequence   
* Initiates the clerk login operation, only one clerk can login at a time
* 
* @rdesc return values.
* @flag int    |  VS_ESCAPE, VS_FAILURE, VS_SUCCESS
* @end
**********************************************************************************************/

int inCPACInitLogInOperation(TRANSACTION_OBJECT* pobTran) {
    int inResult;
    char szMsg[MESSAGE_SIZE + 1];
    int inOperationCode;

    if (inGetClerkMode() == CLERK_LGN) {
        if ((inResult = inCPACGetUDTAnyoneLogedIn(pobTran)) != VS_SUCCESS) {
            //Ensure only one clerk could logged in
            inOperationCode = LOGIN_OPERATION;
            vdSGOpCode(inOperationCode);
            vdClear_8X21_Window(1, 1, 21, inImamLineNumber);
            vdGetMessageFromFile(LOGON_MSG, szMsg);
            vdDisplayAt(obDisp.inHomeCol, 1, szMsg, CLR_EOL); 

            inResult = inCPACCheckLogOn(pobTran);
            while (inResult != VS_SUCCESS) {
                if ((act_kbd_pending_test(KEY_CANCEL) == 1) || (inResult == VS_ERROR))
                    return(VS_ESCAPE);
                vdClearStatusMessage();
                inResult = inCPACCheckLogOn(pobTran);
            }

            vdDisplayMessageFromFile(LOGGED_IN_MSG21, STATUS_MSG);
            pause(50); /* so user can read */
        }
    } else
        return (VS_SUCCESS);

    return(inResult);
}

/********************************************************************************************* 
* @func int | inCPACLogInOperation |
*    
* Initiates the clerk login operation, only one clerk can login at a time
* 
* @rdesc return values.
* @flag int    |  VS_ESCAPE, VS_FAILURE, VS_SUCCESS
* @end
**********************************************************************************************/

int inCPACLogInOperation(TRANSACTION_OBJECT* pobTran) {
    int inResult;

    if (inGetClerkMode() == CLERK_LGN) {
        //Ensure only one clerk could logged in

        inResult = inCPACCheckLogOn(pobTran);
        while (inResult != VS_SUCCESS) {
            if ((act_kbd_pending_test(KEY_CANCEL) == 1) || (inResult == VS_ERROR) || (inResult == VS_ESCAPE))
                return(VS_ESCAPE);
            vdClearStatusMessage();
            inResult = inCPACCheckLogOn(pobTran);
        }

        vdDisplayMessageFromFile(LOGGED_IN_MSG21, STATUS_MSG);
        pause(50); /* so user can read */
    } else {
        vdDisplayMessageFromFile(TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_FAILURE);
    }

    return(inResult);
}

/********************************************************************************************* 
* @func int | inCPACLogOffAllUser |
*  
*  Force to LogOff all user who are logged in already except the input ClerkId
*
*    
* @rdesc return values.
* @flag int    |  VS_SUCCESS, VS_ESCAPE if cancelled, VS_ERR if match not found,
                  VS_FAILURE if file errors
*                 
* @end
**********************************************************************************************/
int inCPACLogOffAllUser(TRANSACTION_OBJECT* pobTran,char* pchClerkId) {
    int inResult = VS_FAILURE;
    int inRecordSize;
    UDT_REC srUDTRec;
    FHANDLE hUDTFHandle;
    int inOperationCode;  /* pj1 */
    char* chNull = 0;

    inOperationCode = inGGOpCode(); /* pj1 */

    inRecordSize = 0;

    if ((hUDTFHandle = open(UDT_FILENAME, O_RDWR)) >= 0) {
        if (lseek(hUDTFHandle, (long) GEN_VER_SIZE, SEEK_SET) == (long) GEN_VER_SIZE)
            do {
                if ((inRecordSize = read(hUDTFHandle, (char *) &srUDTRec, SIZE_UDT_REC)) == SIZE_UDT_REC) {
                    if (strcmp(pchClerkId, srUDTRec.szClerkId) != 0) {
                        if (srUDTRec.inLogedIn == VS_TRUE) {
                            /*  currently logged in, force to logoff */
                            srUDTRec.inLogedIn = VS_FALSE;      
                            if (lseek(hUDTFHandle, ((long) (SIZE_UDT_REC)) * -1, SEEK_CUR) < 0) /* move back file ptr */ {
                                close(hUDTFHandle);
                                return(VS_ERR);
                            }
                            inResult = write(hUDTFHandle, (char *) &srUDTRec, SIZE_UDT_REC); /* update rec */
                            if (inResult != SIZE_UDT_REC)     /* Error writing to file */ {
                                close(hUDTFHandle);
                                return(VS_ERR);
                            }
                        }
                    }
                }
            } while (inRecordSize == SIZE_UDT_REC);

        if (close(hUDTFHandle) < 0)
            return(VS_ERR);
    }
    /* Get out in Clear key press */
    if (act_kbd_pending_test(KEY_CANCEL))
        return (VS_ESCAPE);

    return(VS_SUCCESS);
}

/********************************************************************************************* 
* @func int | inCPACCheckLogOn |
*    
*  This functions checks whether the user logged in to the
*  system has entered correct password or not. The name and
*  password are in  multeventBuf[0] and multeventBuf[1]
* 
* @rdesc return values.
* @flag int    |  VS_SUCCESS, VS_ERR
* @end
**********************************************************************************************/

int inCPACCheckLogOn(TRANSACTION_OBJECT* pobTran) {
    char szClerk[CLERK_ID_SIZE + 1];
    int inResult = VS_ERR;

    if ((inGetClerkMode() == NO_CLERK))
        return(VS_SUCCESS);

    if ((inResult = inEnterWithMessage(lnSelectAppTypePrompt(CLERK_ID_MSG, SERVER_ID_MSG), SCROLL_DISPLAY_FALSE, szClerk, INPUT_ALNUMS, CLERK_ID_SIZE, NULL_PFI)) <= VS_ERR)
        return(inResult);

    while ((inResult = inGetUDTLogedIn(pobTran, szClerk)) != VS_ESCAPE) {
        if (inResult == VS_SUCCESS) {
            if ((inResult = inCPACLogOffAllUser(pobTran, szClerk)) != VS_SUCCESS)
                return(inResult);

            strlcpy(pobTran->srBKey.szClerkId, szClerk, CLERK_ID_SIZE);
            return(inResult);
        } else {
            vdDisplayMessageFromFile(lnSelectAppTypePrompt(INV_CLERK_ERR_MSG21, INV_SERVER_ERR_MSG21), ERROR_MSG);
            vdClearStatusMessage();
        }

        /* Get out in Clear key press */
        if (act_kbd_pending_test(KEY_CANCEL))
            return (VS_ESCAPE);

        if ((inResult = inEnterWithMessage(lnSelectAppTypePrompt(CLERK_ID_MSG, SERVER_ID_MSG), SCROLL_DISPLAY_FALSE, szClerk, INPUT_ALNUMS, CLERK_ID_SIZE, NULL_PFI)) <= VS_ERR)
            return(inResult);
    }  /* end while */



    return(inResult);
}

//Kelvin_f2 --- end: clerk logon/logoff

#undef CPACCLRK_C
#endif /* CLERK_DEFINED */